/*

 */
package com.ohos.connent.accountcloud.biz.modular.dp.service.impl;


import cn.hutool.core.bean.BeanUtil;

import cn.hutool.core.util.ObjectUtil;

import cn.hutool.core.util.PhoneUtil;
import cn.hutool.json.JSONUtil;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fhs.trans.service.impl.TransService;

import com.ohos.connent.accountcloud.biz.core.enums.BizDataTypeEnum;


import com.ohos.connent.accountcloud.biz.modular.dp.entity.DpUser;

import com.ohos.connent.accountcloud.biz.modular.dp.enums.DpExceptionEnum;
import com.ohos.connent.accountcloud.biz.modular.dp.enums.DpUserStatusEnum;
import com.ohos.connent.accountcloud.biz.modular.dp.mapper.DpUserMapper;
import com.ohos.connent.accountcloud.biz.modular.dp.param.*;

import com.ohos.connent.accountcloud.biz.modular.dp.service.DpUserService;

import com.ohos.connent.accountcloud.common.exception.CommonException;
import com.ohos.connent.accountcloud.common.listener.CommonDataChangeEventCenter;

import com.ohos.connent.accountcloud.common.util.*;
import com.ohos.connent.accountcloud.dev.api.DevConfigApi;
import com.ohos.connent.accountcloud.sys.api.SysRoleApi;
import com.ohos.connent.accountcloud.sys.api.SysUserApi;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Objects;


/**
 * 人员Service接口实现类
 *
 *
 **/
@Service
public class DpUserServiceImpl extends ServiceImpl<DpUserMapper, DpUser> implements DpUserService {

    private static final String OHOSCON_SYS_DEFAULT_PASSWORD_KEY = "OHOSCON_SYS_DEFAULT_PASSWORD";

    @Resource
    private TransService transService;

    @Resource
    private DevConfigApi devConfigApi;

    @Resource
    private SysUserApi sysUserApi;


    @Resource
    private SysRoleApi sysRoleApi;

 //   @Resource
//    private DpOrgService dpOrgService;


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void register(DpUserRegisterParam dpUserRegisterParam) {
        DpUser dpUser = BeanUtil.toBean(dpUserRegisterParam, DpUser.class);
        if(ObjectUtil.isEmpty(dpUser.getAvatar())) {
            // 设置默认头像
            dpUser.setAvatar(CommonAvatarUtil.generateImg(dpUser.getAccount()));
        }
        checkRegister(dpUser);
        // SM2解密并获得前端传来的密码哈希值
        String passwordHash;
        try {
            // 解密，并做哈希值
            passwordHash = CommonCryptogramUtil.doHashValue(CommonCryptogramUtil.doSm2Decrypt(dpUser.getPassword()));
        } catch (Exception e) {
            throw new CommonException(DpExceptionEnum.PWD_DECRYPT_ERROR.getValue());
        }
        // 设置密码
        dpUser.setPassword(passwordHash);
        // 设置状态
        dpUser.setUserStatus(DpUserStatusEnum.ENABLE.getValue());
        if(this.save(dpUser)){
            if(BeanUtil.isNotEmpty(dpUserRegisterParam.getRoleIdList())){
                // 进行角色绑定
                sysUserApi.grantRole(dpUser.getId(),dpUserRegisterParam.getRoleIdList());
            }
        }

        // 发布增加事件
        CommonDataChangeEventCenter.doAddWithData(BizDataTypeEnum.USER.getValue(), JSONUtil.createArray().put(dpUser));
    }

    private void checkRegister(DpUser dpUser) {
        if (this.getOne(Wrappers.lambdaQuery(DpUser.class).eq(DpUser::getAccount, dpUser.getAccount())) != null) {
            throw new CommonException(DpExceptionEnum.ACCOUNT_HAS_EXIST.getValue());
        }
        if (this.getOne(Wrappers.lambdaQuery(DpUser.class).eq(DpUser::getPhone, dpUser.getPhone())) != null) {
            throw new CommonException(DpExceptionEnum.PHONE_ALREADY_REGISTERED.getValue());
        }
    }

    @Override
    public void accountExist(DpUserAccountCheckParam dpUserAccountCheckParam){
        QueryWrapper<DpUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(DpUser::getAccount, dpUserAccountCheckParam.getAccount());
        if( this.getOne(queryWrapper) != null) {
            throw new CommonException(DpExceptionEnum.ACCOUNT_HAS_EXIST.getValue());
        }
    }

    @Override
    public void resetPassword(DpUserResetPasswordParam dpUserResetPasswordParam) {
        DpUser dpUser = getOneByNumber(dpUserResetPasswordParam.getNumber());
        dpUser.setPassword(checkAndHashPwd(dpUserResetPasswordParam.getPassword(), dpUser.getPassword()));
        this.updateById(dpUser);

        CommonDataChangeEventCenter.doUpdateWithData(BizDataTypeEnum.USER.getValue(), JSONUtil.createArray().put(dpUser));
    }

    /**
     * 根据号码获取用户信息
     * @param number 手机号/邮箱/账号
     * @return 用户信息
     */
    private DpUser getOneByNumber(String number) {
        DpUser dpUser;
        if (PhoneUtil.isMobile(number)) {
            dpUser = this.getOne(Wrappers.lambdaQuery(DpUser.class).eq(DpUser::getPhone, CommonCryptogramUtil.doSm4CbcEncrypt(number)));
        } else if (CommonEmailUtil.isEmail(number)) {
            dpUser = this.getOne(Wrappers.lambdaQuery(DpUser.class).eq(DpUser::getEmail, number));
        } else {
            dpUser = this.getOne(Wrappers.lambdaQuery(DpUser.class).eq(DpUser::getAccount, number));
        }
        if (BeanUtil.isEmpty(dpUser)) {
            throw new CommonException(DpExceptionEnum.ACCOUNT_NOT_EXIST.getValue());
        }
        return dpUser;
    }


    /**
     * 校验密码和密码做哈希值
     * @param pwdParam 传参中的密码
     * @param pwdUser 用户表中的密码
     * @return
     */
    private String checkAndHashPwd(String pwdParam, String pwdUser) {
        String newPasswordHash;
        try {
            // 解密，并做哈希值
            newPasswordHash = CommonCryptogramUtil.doHashValue(CommonCryptogramUtil.doSm2Decrypt(pwdParam));
        } catch (Exception e) {
            throw new CommonException(DpExceptionEnum.PWD_DECRYPT_ERROR.getValue());
        }
        if (Objects.equals(pwdUser, newPasswordHash)) {
            throw new CommonException(DpExceptionEnum.PWD_SAME_ERROR.getValue());
        }
        return newPasswordHash;
    }

}
